# == Schema Info
# Schema version: 20091029102158
#
# Table name: users
#
#  id                        :integer(4)      not null, primary key
#  activation_code           :string(40)
#  crypted_password          :string(40)
#  email                     :string(100)
#  last_login_ip             :string(30)
#  login                     :string(40)
#  name                      :string(100)     default("")
#  recover_code              :string(255)
#  remember_token            :string(40)
#  salt                      :string(40)
#  state                     :string(255)     default("passive")
#  activated_at              :datetime
#  created_at                :datetime
#  deleted_at                :datetime
#  last_logged_at            :datetime
#  recover_expires_at        :datetime
#  remember_token_expires_at :datetime
#  updated_at                :datetime

class User < ActiveRecord::Base
  acts_as_authorization_subject

  include Authentication
  include Authentication::ByPassword
  include Authentication::ByCookieToken
  include Authorization::AasmRoles
  
  validates_presence_of     :login
  validates_length_of       :login,    :within => 3..40
  validates_uniqueness_of   :login
  validates_format_of       :login,    :with => Authentication.login_regex, :message => Authentication.bad_login_message
  
  validates_presence_of     :name
  validates_format_of       :name,     :with => Authentication.name_regex,  :message => Authentication.bad_name_message
  validates_length_of       :name,     :maximum => 100

  validates_presence_of     :email
  validates_length_of       :email,    :within => 6..100 #r@a.wk
  validates_uniqueness_of   :email
  validates_format_of       :email,    :with => Authentication.email_regex, :message => Authentication.bad_email_message
	
  attr_accessible :email, :name, :password, :password_confirmation, :login, 
                  :avatar_data
	
	before_validation :make_login
	
	has_one :avatar, :as=>:assetable, :dependent=>:destroy
	acts_as_uploaded :avatar
	
	named_scope :activated, :conditions=>"users.activated_at IS NOT NULL", :order=>"login"
	
	def title
		self.name || self.login
	end
	
	def to_param
		"#{self.id}-#{self.login}"
	end
  
  def recover
    self.recover_code = Digest::SHA1.hexdigest("--#{Time.now.to_s}-#{self.email}-#{self.login}--")
	  self.recover_expires_at = Time.now + 24.hours
	  self.save
	  
	  UserMailer.deliver_recover_password(self)
  end
  
  def restore
    self.recover_code = nil
    self.recover_expires_at = nil
    self.save
  end
	
  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  #
  # uff.  this is really an authorization, not authentication routine.  
  # We really need a Dispatch Chain here or something.
  # This will also let us return a human error message.
  #
  def self.authenticate(email, password)
    return nil if email.blank? || password.blank?
    u = find_in_state(:first, :active, :conditions => ["email = :email or login = :email", { :email=>email } ])
    u && u.authenticated?(password) ? u : nil
  end

  def login=(value)
    write_attribute :login, (value ? value.downcase : nil)
  end

  def email=(value)
    write_attribute :email, (value ? value.downcase : nil)
  end
  
  protected
	  def make_login
	    return if self.email.blank?
    	if self.login.blank?
    		tmp_login = self.email.split('@').first
    		tmp_login ||= "#{String.randomize(6)}.join}"
    		tmp_login = tmp_login.parameterize.downcase.gsub('.', '_')
    		tmp_login = "#{tmp_login}_#{String.randomize(4)}.join}" unless User.find_by_login(tmp_login).nil?
    		self.login = tmp_login
    	end
    end
    
    def make_activation_code
      self.deleted_at = nil
      self.activation_code = self.class.make_token
    end
    
    def send_signup_notification
			UserMailer.deliver_signup_notification(self)
		end
end
